package com.anjufang.utils;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.shiro.crypto.RandomNumberGenerator;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.SecureRandom;

/**
 * <p>生成密码工具类</p>
 * @author joel
 * Date:2017年3月14日上午10:45:28 
 * @version
 */
public class PasswordUtil {

	private static RandomNumberGenerator randomNumberGenerator = new SecureRandomNumberGenerator();

	private static String algorithmName = "md5";

	private static String hashIteration = "2";

	private static int hashIterations = Integer.valueOf(hashIteration);

	/**
	 * 加密密码
	 * 
	 * @param loginPwd
	 *            明文密码
	 * @param salt
	 * @return
	 */
	public static String getPwd(String loginPwd, String salt) {
		String newPassword = new SimpleHash(algorithmName, loginPwd, ByteSource.Util.bytes(salt), hashIterations).toHex();
		return newPassword;
	}
	
	/**
	 * 获取加密盐
	 * @param ipv 加密盐向量
	 * @return
	 * @author joel
	 * Date:2017年4月6日下午1:48:20
	 */
	public static String getSalt(String ipv){
		return ipv+randomNumberGenerator.nextBytes().toHex();
	}
	
	/**
	 * 产生随机密码
	 * @param length 长度
	 * @return
	 * @author joel
	 * Date:2017年4月12日下午2:39:56
	 */
	public static String randomAlphanumeric(Integer length){
		return RandomStringUtils.randomAlphanumeric(length);
	}
	
	/**
	 * 生成随机密钥
	 * @param length
	 * @return
	 */
	public static String randomEncodingKey(Integer length){
		return RandomStringUtils.random(length, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*");
	}
	
	/**
	 * AES加密
	 * @param value
	 * @return
	 * @author joel
	 * Date:2017年3月15日上午9:25:05
	 */
	public static byte[] encrypt(String value) {
        byte[] encrypted = null;
        try {

            byte[] raw = new byte[]{'T', 'h', 'i', 's', 'I', 's', 'A', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y'};
            Key skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            byte[] iv = new byte[cipher.getBlockSize()];

            IvParameterSpec ivParams = new IvParameterSpec(iv);
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec,ivParams);
            encrypted  = cipher.doFinal(value.getBytes());
            System.out.println("encrypted string:" + encrypted.length);

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return encrypted;
    }

	/**
	 * AES解密
	 * @param encrypted
	 * @return
	 * @author joel
	 * Date:2017年3月15日上午9:25:27
	 */
    public static  byte[]  decrypt(byte[] encrypted) {
         byte[] original = null;
         Cipher cipher = null;
        try {
            byte[] raw = new byte[]{'T', 'h', 'i', 's', 'I', 's', 'A', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y'};
            Key key = new SecretKeySpec(raw, "AES");
            cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            //the block size (in bytes), or 0 if the underlying algorithm is not a block cipher
            byte[] ivByte = new byte[cipher.getBlockSize()];
            //This class specifies an initialization vector (IV). Examples which use
            //IVs are ciphers in feedback mode, e.g., DES in CBC mode and RSA ciphers with OAEP encoding operation.
            IvParameterSpec ivParamsSpec = new IvParameterSpec(ivByte);
            cipher.init(Cipher.DECRYPT_MODE, key, ivParamsSpec);
            original= cipher.doFinal(encrypted);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return original;
    }
    
    /**
	 * AES密钥随机生成
	 * 
	 * @param encodeRules
	 *            根据ecnodeRules规则初始化密钥生成器
	 * @return
	 * @throws Exception
	 */
	public static byte[] initKey(String encodeRules) throws Exception {
		// 1.构造密钥生成器，指定为AES算法,不区分大小写
		KeyGenerator keygen = KeyGenerator.getInstance("AES");
		// 2.根据ecnodeRules规则初始化密钥生成器
		// 生成一个128位的随机源,根据传入的字节数组
		if (StringUtils.isNotEmpty(encodeRules)) {
			keygen.init(128, new SecureRandom(encodeRules.getBytes()));
		} else {
			keygen.init(128, new SecureRandom());
		}
		// 3.产生原始对称密钥
		SecretKey original_key = keygen.generateKey();
		// 4.获得原始对称密钥的字节数组
		return original_key.getEncoded();
	}
    
    public static void main(String[] args) throws Exception {
    	
    	String base64Encoded = org.apache.shiro.codec.Base64.encodeToString(initKey("rrgzhifupt"));
    	System.out.println(base64Encoded);
    	byte[] base64Decode = org.apache.shiro.codec.Base64.decode(base64Encoded);
    	System.out.println(new String(base64Decode));
	}
}
